﻿namespace PerpetuumSoft.InstrumentationPDA
{
    using PerpetuumSoft.InstrumentationPDA.Mathematics;
    using System;
    using System.Drawing;

    public abstract class CircularControl : CircularControlBase
    {
        private int externalPointerRadius = 0x2d;
        private int internalPointerRadius = 0x19;
        private string[] labels = new string[0];
        private int labelsCount = 5;
        private int labelsRadius = 0x48;
        private bool labelVisible = true;
        private Color pointerColor = Color.Red;
        private decimal pointerSize = 7M;
        private PerpetuumSoft.InstrumentationPDA.PointerType pointerType = PerpetuumSoft.InstrumentationPDA.PointerType.Triangle;
        private int radiusTicks = 50;
        private ColorSection[] sectionsColors = new ColorSection[] { new ColorSection(Color.Black, 60M), new ColorSection(Color.SaddleBrown, 80M), new ColorSection(Color.Red, 100M) };
        private int ticksCount = 10;
        private int ticksLenght = 8;
        private int ticksSubDivisionsCount = 5;
        private bool ticksVisible = true;

        protected CircularControl()
        {
        }

        private void DrawCirclePointer(Graphics g)
        {
            Vector vector = base.ToPoint(base.Value, this.externalPointerRadius) - new Vector(this.pointerSize, this.pointerSize);
            g.FillEllipse(new SolidBrush(this.pointerColor), base.Round(vector.X), base.Round(vector.Y), base.Round(2M * this.pointerSize), base.Round(2M * this.pointerSize));
        }

        protected override void DrawDynamic(Graphics g)
        {
            this.DrawPointer(g);
        }

        private void DrawLinePointer(Graphics g)
        {
            Vector vector = base.ToPoint(base.Value, this.internalPointerRadius);
            Vector vector2 = base.ToPoint(base.Value, this.externalPointerRadius);
            g.DrawLine(new Pen(this.pointerColor), base.Round(vector.X), base.Round(vector.Y), base.Round(vector2.X), base.Round(vector2.Y));
        }

        protected void DrawPointer(Graphics g)
        {
            switch (this.pointerType)
            {
                case PerpetuumSoft.InstrumentationPDA.PointerType.Circle:
                    this.DrawCirclePointer(g);
                    return;

                case PerpetuumSoft.InstrumentationPDA.PointerType.Line:
                    this.DrawLinePointer(g);
                    return;

                case PerpetuumSoft.InstrumentationPDA.PointerType.Triangle:
                    this.DrawTrianglePointer(g);
                    return;
            }
        }

        protected void DrawScale(Graphics g)
        {
            if (this.ticksVisible)
            {
                for (int i = 0; i <= this.ticksCount; i++)
                {
                    decimal num2 = i * 1M / this.ticksCount;
                    decimal num3 = base.PercentToValue(num2);
                    Vector vector = base.ToPoint(num3, this.TicksRadius);
                    Vector vector2 = base.ToPoint(num3, this.TicksRadius + this.ticksLenght);
                    g.DrawLine(new Pen(this.GetColor(num2 * 100M)), base.Round(vector.X), base.Round(vector.Y), base.Round(vector2.X), base.Round(vector2.Y));
                    if (i != this.ticksCount)
                    {
                        for (int j = 1; j < this.ticksSubDivisionsCount; j++)
                        {
                            decimal num5 = num2 + ((j * 1M / this.ticksSubDivisionsCount) / this.ticksCount);
                            decimal num6 = base.PercentToValue(num5);
                            Vector vector3 = base.ToPoint(num6, this.TicksRadius);
                            Vector vector4 = base.ToPoint(num6, (this.ticksLenght / 2) + this.TicksRadius);
                            g.DrawLine(new Pen(this.GetColor(num5 * 100M)), base.Round(vector3.X), base.Round(vector3.Y), base.Round(vector4.X), base.Round(vector4.Y));
                        }
                    }
                }
            }
            if (this.labelVisible)
            {
                int num7;
                bool flag = false;
                if (this.labels != null)
                {
                    for (num7 = 0; num7 < this.labels.Length; num7++)
                    {
                        if ((this.labels[num7] != string.Empty) && (this.labels[num7] != null))
                        {
                            flag = true;
                            break;
                        }
                    }
                }
                int num8 = flag ? (this.labels.Length - 1) : this.labelsCount;
                for (num7 = 0; num7 <= num8; num7++)
                {
                    decimal num9 = (num8 != 0) ? (num7 * 1M / num8) : 0.5M;
                    decimal num10 = base.PercentToValue(num9);
                    string text = base.FormatValue(num10);
                    if (flag)
                    {
                        text = this.labels[num7];
                    }
                    Vector vector5 = new Vector(g.MeasureString(text, this.Font).ToSize());
                    Vector vector6 = base.ToPoint(num10, this.labelsRadius);
                    g.DrawString(text, this.Font, new SolidBrush(this.GetColor(num9)), (float) (vector6.X - (vector5.Width / 2M)), (float) (vector6.Y - (vector5.Height / 2M)));
                }
            }
        }

        protected override void DrawStatic(Graphics g)
        {
            this.DrawScale(g);
        }

        private void DrawTrianglePointer(Graphics g)
        {
            Vector vector = base.ToPoint(base.Value, this.externalPointerRadius);
            Vector vector2 = base.ToPoint(base.Value, this.internalPointerRadius) - base.CenterPoint;
            Vector vector3 = base.ToPoint(base.Value, this.pointerSize) - base.CenterPoint;
            Vector vector4 = vector3;
            decimal num = 1.5707963267948970M;
            vector3.Rotation += num;
            vector4.Rotation += -num;
            Point[] points = new Point[] { vector.Truncate(), ((vector2 + vector3) + base.CenterPoint).Truncate(), ((vector2 + vector4) + base.CenterPoint).Truncate() };
            g.FillPolygon(new SolidBrush(this.pointerColor), points);
        }

        protected Color GetColor(decimal curentValue)
        {
            foreach (ColorSection section in this.SectionsColors)
            {
                if (section.MaximumPercent >= curentValue)
                {
                    return section.Color;
                }
            }
            return Color.Black;
        }

        public int ExternalPointerRadius
        {
            get
            {
                return this.externalPointerRadius;
            }
            set
            {
                if (this.externalPointerRadius != value)
                {
                    this.externalPointerRadius = value;
                    base.Invalidate();
                }
            }
        }

        public int InternalPointerRadius
        {
            get
            {
                return this.internalPointerRadius;
            }
            set
            {
                if (this.internalPointerRadius != value)
                {
                    this.internalPointerRadius = value;
                    base.Invalidate();
                }
            }
        }

        public string[] Labels
        {
            get
            {
                return this.labels;
            }
            set
            {
                if (value == null)
                {
                    value = new string[0];
                }
                this.labels = value;
                base.InvalidateStatic();
            }
        }

        public int LabelsCount
        {
            get
            {
                return this.labelsCount;
            }
            set
            {
                if (value != this.labelsCount)
                {
                    this.labelsCount = value;
                    base.InvalidateStatic();
                }
            }
        }

        public int LabelsRadius
        {
            get
            {
                return this.labelsRadius;
            }
            set
            {
                if (this.labelsRadius != value)
                {
                    this.labelsRadius = value;
                    base.InvalidateStatic();
                }
            }
        }

        public bool LabelsVisible
        {
            get
            {
                return this.labelVisible;
            }
            set
            {
                if (value != this.labelVisible)
                {
                    this.labelVisible = value;
                    base.InvalidateStatic();
                }
            }
        }

        public Color PointerColor
        {
            get
            {
                return this.pointerColor;
            }
            set
            {
                if (value != this.pointerColor)
                {
                    this.pointerColor = value;
                    base.Invalidate();
                }
            }
        }

        public decimal PointerSize
        {
            get
            {
                return this.pointerSize;
            }
            set
            {
                if (value != this.pointerSize)
                {
                    this.pointerSize = value;
                    base.Invalidate();
                }
            }
        }

        public PerpetuumSoft.InstrumentationPDA.PointerType PointerType
        {
            get
            {
                return this.pointerType;
            }
            set
            {
                if (this.pointerType != value)
                {
                    this.pointerType = value;
                    base.Invalidate();
                }
            }
        }

        public ColorSection[] SectionsColors
        {
            get
            {
                return this.sectionsColors;
            }
            set
            {
                if ((value == null) || (value.Length == 0))
                {
                    value = new ColorSection[] { new ColorSection(Color.Black, 100M) };
                }
                this.sectionsColors = value;
                base.InvalidateStatic();
            }
        }

        public int TicksCount
        {
            get
            {
                return this.ticksCount;
            }
            set
            {
                if ((this.ticksCount != value) && (value > 0))
                {
                    this.ticksCount = value;
                    base.InvalidateStatic();
                }
            }
        }

        public int TicksLenght
        {
            get
            {
                return this.ticksLenght;
            }
            set
            {
                if (value != this.ticksLenght)
                {
                    this.ticksLenght = value;
                    base.InvalidateStatic();
                }
            }
        }

        public int TicksRadius
        {
            get
            {
                return this.radiusTicks;
            }
            set
            {
                if (value != this.radiusTicks)
                {
                    this.radiusTicks = value;
                    base.InvalidateStatic();
                }
            }
        }

        public int TicksSubDivisionsCount
        {
            get
            {
                return this.ticksSubDivisionsCount;
            }
            set
            {
                if (value != this.ticksSubDivisionsCount)
                {
                    this.ticksSubDivisionsCount = value;
                    base.InvalidateStatic();
                }
            }
        }

        public bool TicksVisible
        {
            get
            {
                return this.ticksVisible;
            }
            set
            {
                if (value != this.ticksVisible)
                {
                    this.ticksVisible = value;
                    base.InvalidateStatic();
                }
            }
        }
    }
}

